﻿using MikuMikuLibrary.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ft_module_parser.aftconversion
{
    class divamodgen
    {
        public List<divamods> Divamods = new List<divamods>();

        public void SetU1P2P(string pvid, string unlock1p, string unlock2p, string unlock3p, string song_name)
        {
            var d = this.Divamods.Where(c => c.pvid.ToString().Contains(pvid));
            foreach (var i in d)
            {
                i.unlock1p = unlock1p;
                i.unlock2p = unlock2p;
                i.unlock3p = unlock3p;
                i.song_name = song_name;
            }
        }

        public void GenerateDivamodsAFT(string path)
        {

        }

        public void GenerateDivamods(string path, BinaryFormat format = BinaryFormat.FT)
        {
            if (!Directory.Exists(path + "\\divamods"))
                Directory.CreateDirectory(path + "\\divamods");
            int sortindex = 1;
            foreach (var i in Divamods)
            {
                //if (Directory.Exists(path + "\\divamods\\pv_" + i.pvid))
                //    Directory.Delete(path + "\\divamods\\pv_" + i.pvid, true);
                if (!Directory.Exists(path + "\\divamods\\pv_" + i.pvid))
                    Directory.CreateDirectory(path + "\\divamods\\pv_" + i.pvid);
                string modpath = path + "\\divamods\\pv_" + i.pvid + "\\";

                StreamWriter outp = new StreamWriter(modpath + "mod.txt");
                outp.WriteLine("# GENERATED AUTOMATICALLY DO NOT EDIT");
                outp.WriteLine("name=pv_" + string.Format("{0:000}", i.pvid));
                outp.WriteLine("type=pv");
                outp.WriteLine("author=Sega");
                outp.WriteLine("pvid=" + i.pvid);
                outp.WriteLine("ver=2");
                outp.Close();

                outp = new StreamWriter(modpath + "pv_db.txt");
                outp.WriteLine("pv_000.bpm=160");

                if (format == BinaryFormat.FT)
                {
                    outp.WriteLine("pv_000.chainslide_failure_name=slide_ng03");
                    outp.WriteLine("pv_000.chainslide_first_name=slide_long02a");
                    outp.WriteLine("pv_000.chainslide_sub_name=slide_button08");
                    outp.WriteLine("pv_000.chainslide_success_name=slide_ok03");
                }
                outp.WriteLine("pv_000.date=20190501");
                if (format == BinaryFormat.FT)
                    outp.WriteLine("pv_000.difficulty.attribute.original=1");
                if (i.easy)
                {
                    string diff = "easy";
                    if (format == BinaryFormat.F)
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".level=6");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_file_name=rom/script/pv" + i.pvid + "/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + ".dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_format=0x10120116");
                        outp.WriteLine("pv_000.difficulty." + diff + ".version=1");
                    }
                    else
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.edition=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level=PV_LV_06_0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level_sort_index=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_file_name=rom/script/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + "_divax.dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_format=0x11062018");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.version=1");
                    }

                    if (format == BinaryFormat.FT)
                        outp.WriteLine("pv_000.difficulty." + diff + ".length=1");
                }

                if (i.extreme)
                {
                    string diff = "extreme";
                    if (format == BinaryFormat.F)
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".level=6");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_file_name=rom/script/pv" + i.pvid + "/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + ".dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_format=0x10120116");
                        outp.WriteLine("pv_000.difficulty." + diff + ".version=1");
                    }
                    else
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.edition=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level=PV_LV_06_0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level_sort_index=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_file_name=rom/script/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + "_divax.dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_format=0x11062018");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.version=1");
                    }

                    if (format == BinaryFormat.FT)
                        outp.WriteLine("pv_000.difficulty." + diff + ".length=1");
                }

                if (i.hard)
                {
                    string diff = "hard";
                    if (format == BinaryFormat.F)
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".level=6");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_file_name=rom/script/pv" + i.pvid + "/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + ".dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_format=0x10120116");
                        outp.WriteLine("pv_000.difficulty." + diff + ".version=1");
                    }
                    else
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.edition=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level=PV_LV_06_0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level_sort_index=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_file_name=rom/script/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + "_divax.dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_format=0x11062018");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.version=1");
                    }

                    if (format == BinaryFormat.FT)
                        outp.WriteLine("pv_000.difficulty." + diff + ".length=1");
                }

                if (i.normal)
                {
                    string diff = "normal";
                    if (format == BinaryFormat.F)
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".level=6");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_file_name=rom/script/pv" + i.pvid + "/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + ".dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".script_format=0x10120116");
                        outp.WriteLine("pv_000.difficulty." + diff + ".version=1");
                    }
                    else
                    {
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.edition=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level=PV_LV_06_0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.level_sort_index=0");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_file_name=rom/script/pv_" + string.Format("{0:000}", i.pvid) + "_" + diff + "_divax.dsc");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.script_format=0x11062018");
                        outp.WriteLine("pv_000.difficulty." + diff + ".0.version=1");
                    }

                    if (format == BinaryFormat.FT)
                        outp.WriteLine("pv_000.difficulty." + diff + ".length=1");
                }

                outp.WriteLine("pv_000.disp2d.set_name=" + i.pvid);
                if (format == BinaryFormat.F)
                    outp.WriteLine("pv_000.is_extra=1");
                outp.WriteLine("pv_000.lyric.001=");
                outp.WriteLine("pv_000.motion.01=PV" + string.Format("{0:000}", i.pvid) + "_P1");

                if (i.performers == 2)
                    outp.WriteLine("pv_000.motion2P.01=PV" + string.Format("{0:000}", (i.pvid)) + "_P2");

                if (i.performers == 3)
                {
                    outp.WriteLine("pv_000.motion2P.01=PV" + string.Format("{0:000}", (i.pvid)) + "_P2");
                    outp.WriteLine("pv_000.motion3P.01=PV" + string.Format("{0:000}", (i.pvid)) + "_P3");
                }

                outp.WriteLine("pv_000.performer.0.chara=" + i.unlock1p);
                outp.WriteLine("pv_000.performer.0.pv_costume=1");
                if (format == BinaryFormat.F)
                    outp.WriteLine("pv_000.performer.0.size=PLAY_CHARA");
                else
                    outp.WriteLine("pv_000.performer.0.size=NORMAL");
                outp.WriteLine("pv_000.performer.0.type=VOCAL");

                if (i.performers == 2)
                {
                    outp.WriteLine("pv_000.performer.1.chara=" + i.unlock2p);
                    outp.WriteLine("pv_000.performer.1.pv_costume=1");
                    if (format == BinaryFormat.F)
                        outp.WriteLine("pv_000.performer.1.size=PLAY_CHARA");
                    else
                        outp.WriteLine("pv_000.performer.1.size=NORMAL");
                    outp.WriteLine("pv_000.performer.1.type=VOCAL");
                }

                if (i.performers == 3)
                {
                    outp.WriteLine("pv_000.performer.1.chara=" + i.unlock2p);
                    outp.WriteLine("pv_000.performer.1.pv_costume=1");
                    if (format == BinaryFormat.F)
                        outp.WriteLine("pv_000.performer.1.size=PLAY_CHARA");
                    else
                        outp.WriteLine("pv_000.performer.1.size=NORMAL");
                    outp.WriteLine("pv_000.performer.1.type=VOCAL");
                    outp.WriteLine("pv_000.performer.2.chara=" + i.unlock3p);
                    outp.WriteLine("pv_000.performer.2.pv_costume=1");
                    if (format == BinaryFormat.F)
                        outp.WriteLine("pv_000.performer.2.size=PLAY_CHARA");
                    else
                        outp.WriteLine("pv_000.performer.2.size=NORMAL");
                    outp.WriteLine("pv_000.performer.2.type=VOCAL");
                }

                outp.WriteLine("pv_000.performer.num=" + i.performers);

                //outp.WriteLine("pv_000.pv_expression.file_name=rom/pv_expression/exp_P" + i.pvid + ".bin");

                if (i.pv_expr)
                {
                    outp.WriteLine("pv_000.pv_expression.file_name=rom/pv_expression/exp_PV" + String.Format("{0:000}", i.pvid) + ".bin");
                }

                int counter = 0;
                if (format == BinaryFormat.F) counter = 1;
                foreach (var c in i.item_pv)
                {
                    outp.WriteLine("pv_000.pv_item." + string.Format("{0:00}", counter) + "=" + c);
                    counter++;
                }
                if (format == BinaryFormat.F)
                {
                    outp.WriteLine("pv_000.s3d.screen_dist=3.0");
                }
                outp.WriteLine("pv_000.sabi.play_time=25.0");
                outp.WriteLine("pv_000.sabi.start_time=25.0");
                if (format == BinaryFormat.F)
                {
                    outp.WriteLine("pv_000.scratch_name=01_scratch1_D3");
                    outp.WriteLine("pv_000.se_name=01_button1_D3");
                }
                else
                {
                    outp.WriteLine("pv_000.se_name=42_button10");
                    outp.WriteLine("pv_000.slide_name=slide_se13");
                    outp.WriteLine("pv_000.slidertouch_name=slide_windchime");
                }

                outp.WriteLine("pv_000.song_file_name=rom/sound/song/pv_" + string.Format("{0:000}", i.pvid) + ".ogg");
                if (i.song_name != "")
                {
                    if (i.pvid < 800)
                        outp.WriteLine("pv_000.song_name=" + i.song_name + " (Concert)");
                    else outp.WriteLine("pv_000.song_name=" + i.song_name);
                }
                else
                    outp.WriteLine("pv_000.song_name=PV_" + string.Format("{0:000}", i.pvid));
                outp.WriteLine("pv_000.song_name_reading=PV_" + string.Format("{0:000}", i.pvid));
                outp.WriteLine("pv_000.songinfo.arranger=unk");
                if (format == BinaryFormat.FT)
                    outp.WriteLine("pv_000.songinfo.illustrator=unk");
                outp.WriteLine("pv_000.songinfo.lyrics=unk");
                outp.WriteLine("pv_000.songinfo.music=unk");
                if (format == BinaryFormat.FT)
                    outp.WriteLine("pv_000.songinfo.pv_editor=unk");
                if (format == BinaryFormat.FT)
                    outp.WriteLine("pv_000.sudden_timing=0.6");
                if (format == BinaryFormat.F)
                    outp.WriteLine("pv_000.sort_index=" + sortindex);
                //outp.WriteLine("pv_000.title_image.aet_name=title_eff");
                //outp.WriteLine("pv_000.title_image.time=0");

                outp.Close();

                outp = new StreamWriter(modpath + "pv_field.txt");
                int fieldcounter = 0;
                /*
                for (int field = 1; field < 5; field++)
                {
                    //0 = A
                    //1 = B
                    //2 = C
                    //3 = FIN

                    counter = 0;
                    //heh fix later
                    var lista3da = i.a3da.Distinct().ToList();

                    foreach (var c in lista3da.ToList())
                    {
                        if (((c.Contains("_101_"))))
                            lista3da.Remove(c);

                        if (field == 0)
                        {
                            if (((c.Contains("LOOP"))))
                                lista3da.Remove(c);
                            if (((!c.Contains("EFF"))))
                                lista3da.Remove(c);
                        }

                        if (field == 1)
                        {
                            if (((!c.EndsWith("_A")))
                                && (c.Contains("LOOP")))
                                lista3da.Remove(c);

                        }

                        if (field == 2)
                        {
                            if (((!c.EndsWith("_B")))
                                && (c.Contains("LOOP")))
                                lista3da.Remove(c);

                        }


                        if (field == 3)
                        {
                            if (((!c.EndsWith("_C")))
                                && (c.Contains("LOOP")))
                                lista3da.Remove(c);

                        }

                        if (field == 4)
                        {
                            if (lista3da.Any(d => d.Contains("_FIN")))
                            {
                                if (((!c.EndsWith("_FIN")))
                                    && (c.Contains("LOOP")))
                                    lista3da.Remove(c);


                            }
                            else
                            {
                                if (((!c.EndsWith("_C")))
                                && (c.Contains("LOOP")))
                                    lista3da.Remove(c);

                            }
                        }
                        else
                        {
                            if (((c.Contains("_FIN"))))
                                lista3da.Remove(c);
                        }

                    }

                    foreach (var c in lista3da)
                    {
                        if (c.Contains("EFF"))
                        {
                            outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list." + counter + "=-1");
                        }
                        else
                        {
                            if (field == 1)
                                outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list." + counter + "=0");
                            else outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list." + counter + "=-1");

                        };
                        counter++;
                    }
                    outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list.length=" + counter);

                    counter = 0;
                    foreach (var c in lista3da)
                    {
                        outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_list." + counter + "=" + c);
                        counter++;
                    }
                    outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_list.length=" + counter);

                    if (i.pvid < 800)
                        outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".stage=STGPV" + string.Format("{0:000}", (i.pvid + 100)));
                    else outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".stage=STGPV" + string.Format("{0:000}", i.pvid));
                }

                outp.WriteLine("pv_000.field.length=4");
                */

                for (int field = 1; field < 6; field++)
                {
                    //1 = A & INIT
                    //2 = A
                    //3 = B
                    //4 = C
                    //5 = FIN

                    counter = 0;
                    //heh fix later
                    var lista3da = i.a3da.Distinct().ToList();

                    foreach (var c in lista3da.ToList())
                    {
                        if (field == 1)
                        {
                            //if (((c.Contains("LOOP"))))
                            //    lista3da.Remove(c);
                            if (((!c.EndsWith("_A")))
                               && (c.Contains("LOOP")))
                                lista3da.Remove(c);
                            //if (((!c.Contains("EFF"))))
                            //    lista3da.Remove(c);
                        }

                        if (field == 2)
                        {
                            if (((!c.EndsWith("_A")))
                                && (c.Contains("LOOP")))
                                lista3da.Remove(c);
                        }

                        if (field == 3)
                        {
                            if (((!c.EndsWith("_B")))
                                && (c.Contains("LOOP")))
                                lista3da.Remove(c);

                        }


                        if (field == 4)
                        {
                            if (((!c.EndsWith("_C")))
                                && (c.Contains("LOOP")))
                                lista3da.Remove(c);

                        }

                        if (field == 5)
                        {
                            if (lista3da.Any(d => d.Contains("_FIN")))
                            {
                                if (((!c.EndsWith("_FIN")))
                                    && (c.Contains("LOOP")))
                                    lista3da.Remove(c);
                            }
                            else
                            {
                                if (((!c.EndsWith("_C")))
                                && (c.Contains("LOOP")))
                                    lista3da.Remove(c);

                            }
                        }
                        else
                        {
                            if (((c.Contains("_FIN"))))
                                lista3da.Remove(c);
                        }

                    }

                    foreach (var c in lista3da)
                    {
                        if (c.Contains("EFF"))
                        {
                            outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list." + counter + "=-1");
                        }
                        else
                        {
                            if (field == 1)
                                outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list." + counter + "=0");
                            else outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list." + counter + "=-1");

                        };
                        counter++;
                    }
                    outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_frame_list.length=" + counter);

                    counter = 0;
                    foreach (var c in lista3da)
                    {
                        outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_list." + counter + "=" + c);
                        counter++;
                    }
                    outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".auth_3d_list.length=" + counter);

                    if (i.pvid < 800)
                        outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".stage=STGPV" + string.Format("{0:000}", (i.pvid + 100)));
                    else outp.WriteLine("pv_000.field." + string.Format("{0:00}", field) + ".stage=STGPV" + string.Format("{0:000}", i.pvid));
                }
                outp.WriteLine("pv_000.field.length=5");
                outp.Close();
                sortindex++;
            }
        }
    }
}